package hc.server.ui.design.hpj;

import hc.core.util.ByteUtil;
import hc.core.util.HCURL;
import hc.core.util.HCURLUtil;
import hc.server.FileSelector;
import hc.server.ui.design.Designer;
import hc.util.ResourceUtil;

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTree;
import javax.swing.border.TitledBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.tree.MutableTreeNode;

public class MenuItemNodeEditPanel extends ScriptEditPanel {
	private final JRadioButton J_RADIO_BUTTON_SCREEN_USER = new JRadioButton(
			"SCREEN-Mlet");
	private final JRadioButton J_RADIO_BUTTON_SCREEN_DESKTOP = new JRadioButton(
			"SCREEN-Desktop");
	private final JRadioButton J_RADIO_BUTTON_MY_COMMAND = new JRadioButton(
			"CMD-My Command");
	private final JRadioButton J_RADIO_BUTTON_CONFIG = new JRadioButton(
			"CMD-Configration");
	private final JRadioButton J_RADIO_BUTTON_EXIT = new JRadioButton(
			"CMD-Exit / Back");
	private final JRadioButton visiablerb1 = new JRadioButton(),
			visiablerb2 = new JRadioButton(), visiablerb3 = new JRadioButton();
	private final ButtonGroup buttonGroup = new ButtonGroup();
	private final ButtonGroup bgCmdConfig = new ButtonGroup();
	private final ButtonGroup bgScreenConfig = new ButtonGroup();
	private final JRadioButton[] rbs;
	private JPanel exit_config_my_Panle = new JPanel();
	private JPanel screen_config_my_Panle = new JPanel();
	private JPanel myCommand_Panel = new JPanel();
	private HCURL hcurl;
	private JFormattedTextField jtfMyCommand = new JFormattedTextField();
	private JLabel errCommandTip = new JLabel();
	private final JLabel iconLabel = new JLabel();
	private final JButton browIconBtn = new JButton("Select Image [32 X 32]");
	private final ImageIcon sys_icon = Designer.loadImg("hc/server/ui/design/res/hc_32.png");
	private byte[] iconBytes = new byte[1024 * 20];
	
	private void disableAllExcludeCmd(){
		for (int j = 1; j < rbs.length; j++) {
			rbs[j].setEnabled(false);
		}
	}
	
	private void disableTopSwith(int currIdx){
		if(currIdx == 0){
			return;
		}
		
		for (int i = 0; i < rbs.length; i++) {
			if(currIdx == i){
				continue;
			}else{
				rbs[i].setEnabled(false);
			}
		}
	}
	public MenuItemNodeEditPanel() {
		super();
		
		iconByteArrayos.reset(iconBytes, 0);
		
		rbs = new JRadioButton[HPNode.TYPE_MENU_ITEM_SIZE];

		final ItemListener itemListener = new ItemListener() {
			@Override
			public void itemStateChanged(ItemEvent e) {
				if (currItem == null) {
					return;
				}

				final JRadioButton jop = (JRadioButton) e.getSource();
				if (jop.isSelected() == false) {
					return;
				}

				for (int i = 0; i < rbs.length; i++) {
					if (rbs[i] == jop) {
						disableTopSwith(i);

						currItem.type = (i + HPNode.TYPE_MENU_ITEM_CMD);
						hcurl.protocal = getProtocal(currItem.type);
						
						if (currItem.type == HPNode.TYPE_MENU_ITEM_SCREEN) {

							notifyModified();
							
							flip_cmd_screen(false);

							if (hcurl.elementID.equals(HCURL.REMOTE_HOME_SCREEN) || 
									hcurl.elementID.equals(HCURL.DATA_CMD_EXIT)) {//新建且初始值为exit
								J_RADIO_BUTTON_SCREEN_DESKTOP.setSelected(true);
							} else {
								J_RADIO_BUTTON_SCREEN_USER.setSelected(true);
							}
						} else if (currItem.type == HPNode.TYPE_MENU_ITEM_CMD) {
							notifyModified();
							
							flip_cmd_screen(true);

							if (hcurl.elementID.equals(HCURL.DATA_CMD_EXIT)) {
								J_RADIO_BUTTON_EXIT.setSelected(true);
							} else if (hcurl.elementID
									.equals(HCURL.DATA_CMD_CONFIG)) {
								J_RADIO_BUTTON_CONFIG.setSelected(true);
							} else {
								J_RADIO_BUTTON_MY_COMMAND.setSelected(true);
							}
						}
						return;
					}
				}
			}
		};

		final ItemListener myScreen = new ItemListener() {
			@Override
			public void itemStateChanged(ItemEvent e) {
				final JRadioButton source = (JRadioButton) e.getSource();
				if (source.isSelected() == false) {
					return;
				}

				if (source == J_RADIO_BUTTON_SCREEN_DESKTOP) {
					((HPMenuItem)currItem).url = HCURL.URL_HOME_SCREEN;
					myCommand_Panel.setVisible(false);
					tree.updateUI();
					notifyModified();
	//				exit_config_my_Panle.setVisible(false);
				} else if (source == J_RADIO_BUTTON_SCREEN_USER) {
					initMyScreen();
				}
			}
		};
		
		final ItemListener mycommand = new ItemListener() {
			@Override
			public void itemStateChanged(ItemEvent e) {
				final JRadioButton source = (JRadioButton) e.getSource();
				if (source.isSelected() == false) {
					return;
				}

				if (source == J_RADIO_BUTTON_EXIT) {
					((HPMenuItem)currItem).url = HCURL.URL_CMD_EXIT;
					myCommand_Panel.setVisible(false);
					tree.updateUI();
					notifyModified();
				} else if (source == J_RADIO_BUTTON_CONFIG) {
					((HPMenuItem)currItem).url = HCURL.CMD_PROTOCAL + "://"
							+ HCURL.DATA_CMD_CONFIG;
					myCommand_Panel.setVisible(false);
					tree.updateUI();
					notifyModified();
					
					disableAllExcludeCmd();
				} else if (source == J_RADIO_BUTTON_MY_COMMAND) {
					initMyCommand();
				}
			}
		};
		bgCmdConfig.add(J_RADIO_BUTTON_EXIT);
		bgCmdConfig.add(J_RADIO_BUTTON_CONFIG);
		bgCmdConfig.add(J_RADIO_BUTTON_MY_COMMAND);
		
		bgScreenConfig.add(J_RADIO_BUTTON_SCREEN_DESKTOP);
		bgScreenConfig.add(J_RADIO_BUTTON_SCREEN_USER);
		
		J_RADIO_BUTTON_EXIT.addItemListener(mycommand);
		J_RADIO_BUTTON_CONFIG.addItemListener(mycommand);
		J_RADIO_BUTTON_MY_COMMAND.addItemListener(mycommand);
		
		J_RADIO_BUTTON_SCREEN_DESKTOP.addItemListener(myScreen);
		J_RADIO_BUTTON_SCREEN_USER.addItemListener(myScreen);
		
		J_RADIO_BUTTON_SCREEN_USER.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				hcurl.elementID = "myScreen" + MenuManager.getNextNodeIdx();//self.getCurrNode().getParent().getChildCount()
				initMyScreen();
				verify(true);
			}
		});
		
		J_RADIO_BUTTON_MY_COMMAND.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				hcurl.elementID = "doBiz" + MenuManager.getNextNodeIdx();//self.getCurrNode().getParent().getChildCount()
				initMyCommand();
				verify(true);
			}
		});
		exit_config_my_Panle.setLayout(new FlowLayout(FlowLayout.LEFT));
		exit_config_my_Panle.add(new JLabel("CMD Type : "));
		exit_config_my_Panle.add(J_RADIO_BUTTON_EXIT);
		exit_config_my_Panle.add(J_RADIO_BUTTON_CONFIG);
		exit_config_my_Panle.add(J_RADIO_BUTTON_MY_COMMAND);
		
//		JPanel screen_Panel = new JPanel();
		screen_config_my_Panle.setLayout(new FlowLayout(FlowLayout.LEFT));
		screen_config_my_Panle.add(new JLabel("Screen Type : "));
		screen_config_my_Panle.add(J_RADIO_BUTTON_SCREEN_DESKTOP);
		screen_config_my_Panle.add(J_RADIO_BUTTON_SCREEN_USER);

		JPanel cmd_url_panel = new JPanel();
		cmd_url_panel.setLayout(new FlowLayout(FlowLayout.LEFT));
		cmd_url_panel.add(new JLabel("target locator :"));
		cmd_url_panel.add(jtfMyCommand);
		cmd_url_panel.add(testBtn);
		cmd_url_panel.add(errCommandTip);
		errCommandTip.setVisible(false);
		errCommandTip.setForeground(Color.RED);

		jtfMyCommand.setColumns(30);
		jtfMyCommand.setFocusLostBehavior(JFormattedTextField.COMMIT);
		jtfMyCommand.getDocument().addDocumentListener(new DocumentListener() {
			private void modify(){
				verify(false);
			}
			@Override
			public void removeUpdate(DocumentEvent e) {
				modify();
			}
			
			@Override
			public void insertUpdate(DocumentEvent e) {
				modify();
			}
			
			@Override
			public void changedUpdate(DocumentEvent e) {
				modify();
			}
		});
		jtfMyCommand.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				verify(true);
			}
		});
		myCommand_Panel.setLayout(new BorderLayout());
		myCommand_Panel.add(cmd_url_panel, BorderLayout.NORTH);
		JPanel jtascriptPanel = new JPanel();
		jtascriptPanel.setBorder(new TitledBorder(
				"JRuby script for my biz :"));
		jtascriptPanel.setLayout(new BorderLayout());
		
		jtascriptPanel.add(scrollpane, BorderLayout.CENTER);
		jtascriptPanel.add(errRunInfo, BorderLayout.SOUTH);
		myCommand_Panel.add(jtascriptPanel, BorderLayout.CENTER);

		JPanel total_my_panel = new JPanel();
		total_my_panel.setLayout(new BorderLayout());
		JPanel cmd_screen_panel = new JPanel();
		cmd_screen_panel.setLayout(new FlowLayout(FlowLayout.LEFT));
		cmd_screen_panel.add(exit_config_my_Panle);
		cmd_screen_panel.add(screen_config_my_Panle);
		total_my_panel.add(cmd_screen_panel, BorderLayout.NORTH);
		total_my_panel.add(myCommand_Panel, BorderLayout.CENTER);

		JPanel namePanel = new JPanel();
		namePanel.setLayout(new FlowLayout(FlowLayout.LEFT));
		namePanel.add(new JLabel("Display Name :"));
		nameField.setColumns(10);
		namePanel.add(nameField);
		iconLabel.setIcon(sys_icon);
		namePanel.add(iconLabel);
		browIconBtn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				BufferedImage bi;
				try {
					final File selectImageFile = FileSelector.selectImageFile(tree, FileSelector.IMAGE_FILTER, true);
					if(selectImageFile == null){
						return;
					}
					bi = ImageIO.read(selectImageFile);
				} catch (IOException e2) {
					JOptionPane.showMessageDialog(tree, e.toString(), "Error select resource!", JOptionPane.ERROR_MESSAGE);
					return;
				}
				if(bi != null){
					//32 X 32
					if(bi.getWidth() != 32){
						bi = ResourceUtil.resizeImage(bi, 32, 32);
					}
//					if(light == null){
//						light = (BufferedImage)Designer.loadImg("hc/server/ui/design/res/lightfil_32.png").getImage();
//					}

					bi = makeRoundedCorner(bi, 12);//composeImage(bi, light)
					
					int doubleSize = bi.getHeight() * bi.getWidth() * 2;
					if(iconBytes.length < doubleSize){
						iconBytes = new byte[doubleSize];
						iconByteArrayos.reset(iconBytes, 0);
					}else{
						iconByteArrayos.reset();
					}
					try {
						ImageIO.write(bi, "png", iconByteArrayos);
					} catch (Exception e1) {
						return;
					}
					final int pngDataLen = iconByteArrayos.size();
					byte[] data = new byte[pngDataLen];
					System.arraycopy(iconBytes, 0, data, 0, pngDataLen);
					
					((HPMenuItem)currItem).imageData = ByteUtil.encodeBase64(data);
					notifyModified();
					
					iconLabel.setIcon(new ImageIcon(bi));
				}
			}
		});
		namePanel.add(browIconBtn);
		
		
		JPanel radioButPanel = new JPanel();
		radioButPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
		radioButPanel.add(new JLabel("Target Type :"));
		for (int i = 0; i < rbs.length; i++) {
			rbs[i] = new JRadioButton(HPMenuItem.getTypeDesc(i
					+ HPNode.TYPE_MENU_ITEM_CMD));

			buttonGroup.add(rbs[i]);
			rbs[i].addItemListener(itemListener);
			radioButPanel.add(rbs[i]);
		}

		JPanel gridPanel = new JPanel();
		gridPanel.setLayout(new BorderLayout());
		gridPanel.add(radioButPanel, BorderLayout.NORTH);
		gridPanel.add(total_my_panel, BorderLayout.CENTER);

		setLayout(new BorderLayout());
		add(namePanel, BorderLayout.NORTH);
		add(gridPanel, BorderLayout.CENTER);

		buttonGroup.add(visiablerb1);
		bgCmdConfig.add(visiablerb2);
		bgScreenConfig.add(visiablerb3);
	}
	
	private void flip_cmd_screen(boolean visiable){
		exit_config_my_Panle.setVisible(visiable);
		screen_config_my_Panle.setVisible(!visiable);
	}
	
	@Override
	Map<String, String> buildMapScriptParameter(){
		return RubyExector.toMap(hcurl);
	}
	
	public boolean verify(boolean refresh) {
		final String text = jtfMyCommand.getText();
		if (text.length() < 1) {
			errCommandTip.setVisible(true);
			errCommandTip.setText("error empty");
			return false;
		}
		if (text.startsWith("_")) {
			errCommandTip.setVisible(true);
			errCommandTip.setText("start with char '_'");
			return false;
		}
		if (text.indexOf("/") >= 0) {
			errCommandTip.setVisible(true);
			errCommandTip.setText("invalid char /");
			return false;
		}
		errCommandTip.setVisible(false);
		((HPMenuItem)currItem).url = hcurl.protocal + "://" + text;
		try{
			hcurl = HCURLUtil.extract(((HPMenuItem)currItem).url);
		}catch (Exception e) {
			
		}
		if(refresh){
////		if(searchSameElementID(tree, currItem.type, hcurl.elementID) > 1){
//			errCommandTip.setVisible(true);
//			errCommandTip.setText("'" + hcurl.elementID + "' is used by item");
//			return false;
//		}
			tree.updateUI();
		}
		notifyModified();
		return true;
	}
	private static final int[] URL_PROTOCAL_CODE = {HPNode.TYPE_MENU_ITEM_CMD, HPNode.TYPE_MENU_ITEM_SCREEN, 
		HPNode.TYPE_MENU_ITEM_FORM, HPNode.TYPE_MENU_ITEM_SUB_MENU};
	
	public static String getProtocal(int code){
		for (int i = 0; i < URL_PROTOCAL_CODE.length; i++) {
			if(code == URL_PROTOCAL_CODE[i]){
				return HCURL.URL_PROTOCAL[i];
			}
		}
		return "";
	}
	
	@Override
	public void init(MutableTreeNode data, JTree tree) {
		super.init(data, tree);

		hcurl = HCURLUtil.extract(((HPMenuItem)currItem).url, false);

		currItem.type = (HCURL.getURLProtocalIdx(hcurl.protocal) + HPNode.TYPE_MENU_ITEM_CMD);

		disableButtonGroup();

		rbs[currItem.type - HPNode.TYPE_MENU_ITEM_CMD].setSelected(true);
		
		if(((HPMenuItem)currItem).imageData.equals(HPMenuItem.SYS_DEFAULT_ICON)){
			iconLabel.setIcon(sys_icon);
		}else{
			byte[] bs = ByteUtil.decodeBase64(((HPMenuItem)currItem).imageData);
			ImageIcon icon = new ImageIcon(bs);
			iconLabel.setIcon(icon);
		}
		super.isInited = true;
	}

	private void disableButtonGroup() {
		for (int j = 0; j < rbs.length; j++) {
			rbs[j].setEnabled(true);
		}
		J_RADIO_BUTTON_EXIT.setEnabled(true);
		J_RADIO_BUTTON_CONFIG.setEnabled(true);

		J_RADIO_BUTTON_SCREEN_DESKTOP.setEnabled(true);

		visiablerb1.setSelected(true);
		visiablerb2.setSelected(true);
		visiablerb3.setSelected(true);
	}
	
	private void initMyCommand() {
		notifyModified();
		
		disableAllExcludeCmd();
		
		J_RADIO_BUTTON_EXIT.setEnabled(false);
		J_RADIO_BUTTON_CONFIG.setEnabled(false);

		initScript();
	}

	private void initScript() {
		int pnum = hcurl.getParaSize();
		String pv = "";
		for (int i = 0; i < pnum; i++) {
			if (pv.length() > 0) {
				pv += "&";
			}
			final String key = hcurl.getParaAtIdx(i);
			pv += key + "=" + hcurl.getValueofPara(key);
		}
		jtfMyCommand.setText(hcurl.elementID
				+ ((pv.length() > 0) ? ("?" + pv) : ""));
		final String listener = ((HPMenuItem)currItem).listener;
		jtaScript.setText(listener == null ? "" : listener);
		
		//代码很长时，置于首行
		jtaScript.setCaretPosition(0);
		
		initColor();
		myCommand_Panel.setVisible(true);
	}

	private void initMyScreen() {
		notifyModified();
		
//		for (int j = 1; j < rbs.length; j++) {
//			rbs[j].setEnabled(false);
//		}

		J_RADIO_BUTTON_SCREEN_DESKTOP.setEnabled(false);

		initScript();
	}

	public static BufferedImage composeImage(BufferedImage base, BufferedImage cover){
		BufferedImage bi = new BufferedImage(base.getWidth(), base.getHeight(), BufferedImage.TYPE_INT_ARGB);
	    Graphics2D g2d = bi.createGraphics();
		g2d.setComposite(AlphaComposite.SrcOver);
	    g2d.drawImage(base, 0, 0, null);
		g2d.setComposite(AlphaComposite.SrcOver);
		g2d.drawImage(cover, 0, 0, null);
		return bi;
	}


	public static BufferedImage makeRoundedCorner(BufferedImage image, int cornerRadius) {
		int w = image.getWidth();
		int h = image.getHeight();
		BufferedImage output = new BufferedImage(w, h,
				BufferedImage.TYPE_INT_ARGB);
		Graphics2D g2 = output.createGraphics();
		g2.setComposite(AlphaComposite.Src);
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.WHITE);
        g2.fill(new RoundRectangle2D.Float(0, 0, w, h, cornerRadius,
                cornerRadius));

        g2.setComposite(AlphaComposite.SrcIn);
        g2.drawImage(image, 0, 0, null);
        
        g2.dispose();
	
		return output;
	}

	@Override
	public void updateScript(String script) {
		((HPMenuItem)currItem).listener = script;
	}


}